package com.kingmed.kmss.bpmn.flow.listener;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import com.kingmed.kmss.bpmn.modules.backup.service.BizApprovalStatusService;
import com.kingmed.kmss.bpmn.flow.service.custom.ProcessStatusSyncServiceImpl;
import com.kingmed.kmss.common.constant.bpmn.BpmnConstant;
import com.kingmed.kmss.common.constant.bpmn.ProcessConstant;
import com.kingmed.kmss.common.constant.common.OperatorConstants;
import com.kingmed.kmss.common.enums.bpmn.ProcessType;
import com.kingmed.kmss.common.exception.BusinessException;
import com.kingmed.kmss.common.exception.bpmn.ProcessNoAuditUserException;
import com.kingmed.kmss.common.utils.AppContextUtil;
import com.kingmed.kmss.framework.feign.client.admin.CommonAdminFeignServiceFacade;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.task.service.delegate.DelegateTask;

import java.util.*;

/**
 * 任务监听器 - 根据创建者子公司或大区属性从角色用户中筛选实际审批者（这里主要是用来保存审批跟踪数据）
 *
 * @author wzg
 */
@Slf4j
public class AssignUserTaskListener implements TaskListener {

    /**
     *
     */
    private static final long serialVersionUID = -7589962189182004091L;

    protected CommonAdminFeignServiceFacade adminRemoteSvc = AppContextUtil.getBean(CommonAdminFeignServiceFacade.class);
    protected BizApprovalStatusService bizStatusSvc = AppContextUtil.getBean(BizApprovalStatusService.class);

    protected ProcessStatusSyncServiceImpl procStatusSvc = AppContextUtil.getBean(ProcessStatusSyncServiceImpl.class);


    @Override
    public void notify(DelegateTask delegateTask) {
        try {

            log.debug("任务监听器 - 根据角色分配用户");

            //从delegateTask获取流程变量
            String bizType = (String) delegateTask.getVariable(BpmnConstant.VarKeys.BIZ_TYPE);
            String bizId = (String) delegateTask.getVariable(BpmnConstant.VarKeys.BIZ_ID);
            String procInstId = delegateTask.getProcessInstanceId();
            String bizTitle = (String) delegateTask.getVariable(BpmnConstant.VarKeys.BIZ_TITLE);
            ProcessType processType = (ProcessType) delegateTask.getVariable(BpmnConstant.VarKeys.PROCESS_TYPE);
            String contractEndDate = (String) delegateTask.getVariable(BpmnConstant.VarKeys.CONTRACT_END_DATE);
            Map<String,Object> paramMap = new HashMap<>();
            paramMap.put(BpmnConstant.VarKeys.CONTRACT_END_DATE, contractEndDate);
            //任务候选人
            List<String> candidateUsers = Lists.newArrayList();
            // 如果当前任务已经分配用户（不需要根据角色选取业务上的用户，只保存当前处理人到流程状态表）
            String assignee = delegateTask.getAssignee();
            if (StringUtils.isNotEmpty(assignee) && !assignee.contains(OperatorConstants.A_SEMICOLON_KEY)) {
                delegateTask.setAssignee(assignee + OperatorConstants.A_SEMICOLON_KEY);
                candidateUsers.add(assignee);
            }
            // 分配了多个用户
            if (StringUtils.isNotBlank(assignee) && assignee.contains(OperatorConstants.A_SEMICOLON_KEY)) {
                String[] assigees = assignee.split(OperatorConstants.A_SEMICOLON_KEY);
                candidateUsers.addAll(Arrays.asList(assigees));
                delegateTask.setAssignee(assignee.endsWith(OperatorConstants.A_SEMICOLON_KEY) ? assignee : assignee + OperatorConstants.A_SEMICOLON_KEY);
            }
            // 如果是根据审批角色确定assignee
            if (CollUtil.isNotEmpty(delegateTask.getCandidates())) {
                candidateUsers = getBusinessAssignee(delegateTask);
            }
            //如果找不到人
            if (CollUtil.isEmpty(candidateUsers)) {
                String taskName = delegateTask.getName();
                String msg = String.format("无法找到下一个审批任务处理人, 审批角色: %s", taskName);
                log.error(msg);
                throw new ProcessNoAuditUserException(msg);
            }
            // 保存下一任务信息到状态表
            bizStatusSvc.updateNextAssignees(bizType, bizId, candidateUsers, procInstId);
            //更新业务表
            procStatusSvc.syncProcessStatus(bizType, bizId, bizTitle, ProcessConstant.Status.APPROVING, processType, paramMap);
        } catch (Exception e) {
            throw new BusinessException(e.getMessage(), e);
        }

    }

    protected List<String> getBusinessAssignee(DelegateTask delegateTask) {
        Set<IdentityLink> candidates = delegateTask.getCandidates();
        String groupId = "";
        if (candidates != null && !candidates.isEmpty()) {
            groupId = candidates.iterator().next().getGroupId();
        }

        Integer orgType = (Integer) delegateTask.getVariable(BpmnConstant.VarKeys.ORG_TYPE);
        Long parentOrgId = (Long) delegateTask.getVariable(BpmnConstant.VarKeys.PARENT_ORG_ID);

        log.info("读取审批角色信息: " + groupId);
        // 根据用户组织属性查找匹配审批人员（子公司，大区）
        List<String> candidateUsers = adminRemoteSvc.getRoleUsersByOrg(groupId, orgType, String.valueOf(parentOrgId));
        log.info("角色全部用户: " + candidateUsers);


        delegateTask.setAssignee(StringUtils.join(candidateUsers.toArray(),
                OperatorConstants.A_SEMICOLON_KEY) + OperatorConstants.A_SEMICOLON_KEY);
        return candidateUsers;
    }

}
